\documentclass{article}
\usepackage{geometry}
\geometry{margin=1.5cm, vmargin={0pt,1cm}}
\setlength{\topmargin}{-1cm}
\setlength{\paperheight}{29.7cm}
\setlength{\textheight}{25.3cm}

% useful packages.
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{enumerate}
\usepackage{graphicx}
\usepackage{subfigure}
\usepackage{multicol}
\usepackage{fancyhdr}
\usepackage{layout}
\usepackage{ctex}
\usepackage{listings}

% some common command
\newcommand{\dif}{\mathrm{d}}
\newcommand{\avg}[1]{\left\langle #1 \right\rangle}
\newcommand{\difFrac}[2]{\frac{\dif #1}{\dif #2}}
\newcommand{\pdfFrac}[2]{\frac{\partial #1}{\partial #2}}
\newcommand{\OFL}{\mathrm{OFL}}
\newcommand{\UFL}{\mathrm{UFL}}
\newcommand{\fl}{\mathrm{fl}}
\newcommand{\op}{\odot}
\newcommand{\Eabs}{E_{\mathrm{abs}}}
\newcommand{\Erel}{E_{\mathrm{rel}}}

\usepackage{xcolor}
\usepackage{fontspec} 
\definecolor{dkgreen}{rgb}{0,0.6,0}
\definecolor{gray}{rgb}{0.5,0.5,0.5}
\definecolor{comment}{rgb}{0.56,0.64,0.68}


\begin{document}
\title{Project \#2}
\pagestyle{fancy}
\lhead{Name Li HuiTeng 3180102114}
\chead{ numPDE}
\rhead{Date 21.06.10}

\section*{1. 实验目的}
多重网格法是一种迭代效率很高的方法。由于它是插值法与迭代法的结合，迭代法负责对付高频波，插值法负责对付平滑波，还可以通过
在不同层级网格间上下移动来改变误差波的相对于网格的频率，故它对于任意频次的误差波都有很优良的消杀能力。我们其实可以证明，
如果使用的是V-cycle，那时间复杂度为O(Nlog(N));如果是FMG，那还可以达到更匪夷所思的O(N)!

既然这方法听起来这么美好，那么可能有人就想问了：听起来MG是很fancy，那么，它的代价是什么？
我思考了一下，觉得它的代价就是在实际中做起来太累了，或者说太金贵——其中主要一个原因就是它对边界的形状与性状是很敏感的。我们算的再复杂，起码也还是正方形区域，但如果
这个正方形区域缺了个角怎么办？我们会发现，我们很难继续无忧无虑的再无脑二等分下去了。理论都不适用了。所以这其实也是一个很值得思考的问题，但是限于时间我也没
法去事件算一算。

\section*{2. 实验完成情况}
本次实验在C++环境下实现，编写的代码用于对一维与二维的Possion方程在Dirichlect条件下进行数值求解。

尝试性的使用了factory type.目的是为了让我们的插值算子与限制算子有朝一日可以移植到其他地方上（例如混合边界条件），不用被我们的题目中具体的类所困住出不来。我想这种移植的
友好性才是我们使用factory type 的目的吧。所以虽然还有些东西也可以抽象出来，例如初始化函数与残差计算函数，但它们都依赖于具体的问题，抽象出来也不太可能今后代码复用，所以
就收手了。

当然，同样令人不愉快的是，虽然勉强解决了factory，但我在这次实验的makefile文件还是对人类有些不友好。

主要时间预算不够，之前跌坑去了。因为讲义上的矩阵形式印象过于深刻，所以我一开始还真的用矩阵形式来存储所有算子（甚至包括GaussSeidal迭代）——后来我发现，对于稀疏矩阵，根本没必要写个大矩阵。
这也是一个很有趣的事情。有时候，理论是一回事，但计算是另一回事。就比如说我们讲义定义的残差，那种用真值减估算值其实是很反数学直觉的。但是没办法，为了服务于多重网格理论最重要的
残差等价定理，我们只能这么定义;不然就面临着V-cylce中的递归形式崩塌的风险。所以学我们这门课确实得动手算的。

关于这个makefile问题，我会尽力在以后的编程实践中解决。

\section*{3. 实验结果展示}
通过文件夹dMakefile文件,我们可以在终端输入作业要求中的指令来实现相应功能。当然，尴尬的是，make answers 要得到全部结果，得运行相当长的时间（5-10 min）：这可能是因为我设定的可供选择的参数不仅有维数，还有smoothe
多了一种Gauss seidal迭代的缘故。当然，我相信应该不是我程序写错了。因为对于n=1024与n=128,为达到相对精确为1e-8,我们的V-cycle自迭代次数是几乎完全一致的。这就是我们多重网格的一个显著特征。尽管时间长短会有体感区别，但
由于不是经典迭代法的O（N*N）,所以矩阵规模的扩大并不会给我们的精度与迭代时间带来灾难性后果。我也在document文档放置了所有重定向生成文件的备份，可以直接查看检验。

另外，关于问题（3）的回答，经测试我发现大概在3.8*1e-16左右，是大多数V-cycle是无法逾越的关卡。但我对这个问题其实不太信服。因为我们计算机double的精度也大概在1e-16,所以完全有可能就是我们的机器的截断，而非algebraic error
或者离散误差。而且我试验了一下，发现如果改用long double，那么single V-cycle的相对精度也是在某些问题下也是可以达到1e-17量级的（且在百次自迭代内）（采用加权GS-smoothe）。但是那个测试程序跟我现在重构的factory mode 不兼容，
所以也没放进来。 （难道意思是，猜到了正常都会只用 double 吗）

\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 
